12. New Tweet Component

L712 New Tweet UI V2

Adding a New Tweet

Let’s now work on the logic of adding a new tweet. Once the user submits a new tweet, it should show up in the list of all of tweets and be added to our database. Since this tweet will be used by more than one component, we know that we want to make sure the store is modified to reflect the updated list of tweets. Recording tweets in a database is an asynchronous operation, so we can use Redux Thunk to issue the API request.

L715 New Tweet Logic Actions V1

Let’s quickly cover a common JavaScript bug at this point.

Make sure that whenever an arrow function has curly braces, you’re using a return statement, if you want to return something.

Common Bug - ES6

Given this array, const nums = [1,2,3]; Which statements produce the following output [3,3,3] ? Select all that apply.

SOLUTION:
  • `nums.map(num => nums.length);`
  • `nums.map(num => { return nums.length });`

We know that our store looks like this:

{
  tweets: {
    tweetId: { tweetId, authorId, timestamp, text, likes, replies, replyingTo}, 
    tweetId: { tweetId, authorId, timestamp, text, likes, replies, replyingTo}
  },
  users: {
    userId: {userId, userName, avatar, tweets array},
    userId: {userId, userName, avatar, tweets array}
  },
  authedUser: userId
}

Let’s start working on the New Tweet Reducer. How will we be modifying the state to reflect the new tweet?

This is going to be a two-part process:

  1. the new tweet needs to be added to the list of tweets
  • an already existing tweet needs to be modified if the new tweet is a response to another tweet

In this reducer, we'll 1) concatenate the new tweet to the list of the already-existing tweets. Remember that the object spread operator offers us the most concise way of doing that; and 2) modify the replies property of the tweet the new tweet is replying to.

L736 New Tweet Logic Reducer V1

L737 New Tweet Logic Component V1

In Step 2 of the Planning Stage, we determined that the New Tweet Component will show up inside of the App Component when the user goes to the /new page and that it will be inside of the Tweet Page Component when the user is on the /tweet/:id page.

When the user is at the /new route, the new tweet will not be attached to another tweet. When the user is at the tweet/:id route, the new tweet will be attached to the already-displayed tweet. Notice that the route already contains the parent tweet’s id. We can just pass the id from the route to the New Tweet Component whenever we’re creating a reply tweet.

What happens when someone clicks “Submit” to add a new tweet? The New Tweet Component will need to communicate with our store. We communicate with the store by dispatching actions. dispatch is a method on the store. That means that the New Tweet Component needs to be connect()ed to Redux. Once a component is connected to the store, it will have dispatch on its props.

When will the mapStateToProps function be called? Select all that apply.

SOLUTION:
  • Anytime the store is updated
  • Whenever the component receives new props.

L714 Tweet Page V2

Lesson Challenge

Suppose we replaced the case ADD_TWEET: portion of the code in the reducers/tweets file with the code below.

  • Would the state change in the same way? Why or why not?
  • Would the new tweet appear on the page? Why or why not?

Run the code to check your answer.

...
case ADD_TWEET :
   const { tweet } = action

   let replyingTo = {}
   if (tweet.replyingTo !== null) {
      const allReplies = state[tweet.replyingTo].replies.concat([tweet.id]);

      return {
      ...state,
      [action.tweet.id]: action.tweet,
      [action.tweet.replyingTo.replies]: allReplies
      }
   }

   return {
      ...state,
      [action.tweet.id]: action.tweet,
      ...replyingTo,
   }
...

Further Learning

Carefully go over the Immutable Update Patterns and Designing the State Shape pages in the Redux documentation.